001 package EVolve; 002 003 /* EVolve - an Extensible Software Visualization Framework 004 * Copyright (C) 2001-2002 Qin Wang 005 * 006 * This library is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Library General Public 008 * License as published by the Free Software Foundation; either 009 * version 2 of the License, or (at your option) any later version. 010 * 011 * This library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Library General Public License for more details. 015 * 016 * You should have received a copy of the GNU Library General Public 017 * License along with this library; if not, write to the 018 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 019 * Boston, MA 02111-1307, USA. 020 */ 021 022 /* 023 * EVolve is distributed at http://www.sable.mcgill.ca/EVolve/ 024 */ 025 026 import EVolve.*; 027 import EVolve.exceptions.DataProcessingException; 028 import EVolve.exceptions.CancelLoadDataException; 029 import EVolve.exceptions.EVolveException; 030 import EVolve.data.NumericStringComparator; 031 import EVolve.data.*; 032 import java.io.*; 033 import java.util.*; 034 import javax.swing.*; 035 036 public class DemoSource implements DataSource { 037 private final String dsourceName = "DemoSource"; 038 private String fn = null; // data file name 039 040 private RandomAccessFile file; 041 042 private EntityBuilder classBuilder; 043 044 private EntityBuilder threadBuilder; 045 046 private EntityBuilder methodBuilder; 047 private FieldDefinition methodDefiningClass; 048 049 private EntityBuilder locationBuilder; 050 051 private EntityBuilder sizeBuilder; 052 053 private EventBuilder allocationBuilder; 054 private FieldDefinition allocationObjectCount; 055 private FieldDefinition allocationObjectSize; 056 private FieldDefinition allocationBytecode; 057 private FieldDefinition allocationObjectType; 058 private FieldDefinition allocationThread; 059 private FieldDefinition allocationMethod; 060 private FieldDefinition allocationLocation; 061 private FieldDefinition allocationSize; 062 private FieldDefinition allocationFieldSum; 063 private FieldDefinition allocationFieldCounter; 064 065 private EventBuilder invocationBuilder; 066 private FieldDefinition invocationNumber; 067 private FieldDefinition invocationBytecode; 068 private FieldDefinition invocationThread; 069 private FieldDefinition invocationMethod; 070 private FieldDefinition invocationLocation; 071 private FieldDefinition invocationFieldCounter; 072 073 074 private ElementDefinition[] definition; 075 private int definitionCounter; 076 077 private TreeMap classMap; 078 private TreeMap threadMap; 079 private TreeMap methodMap; 080 private TreeMap locationMap; 081 private TreeMap sizeMap; 082 083 private long counter[]; 084 085 public void init() throws EVolveException { 086 String lastName = fn; 087 088 fn = Scene.getDataFileName(); 089 if (fn == null) { 090 JFileChooser fc = new JFileChooser(Scene.getUIManager().getLastDataDir()); 091 if (fc.showOpenDialog(Scene.getFrame()) == JFileChooser.APPROVE_OPTION) { 092 try { 093 file = new RandomAccessFile(fc.getSelectedFile(), "r"); 094 fn = fc.getSelectedFile().getName(); 095 Scene.setDataFilename(fc.getSelectedFile().getPath()); 096 Scene.getUIManager().setLastDataDir(fc.getSelectedFile().getPath()); 097 Scene.setDataFilename(null); 098 } catch (IOException e) { 099 throw new DataProcessingException("IO exception occurred when access data file."); 100 } 101 } else { 102 fn = lastName; 103 throw new CancelLoadDataException(); 104 } 105 } else { 106 try { 107 file = new RandomAccessFile(fn, "r"); 108 } catch (IOException e) { 109 throw new DataProcessingException("File loading failed."); 110 } 111 } 112 113 } 114 115 public void startBuildDefinition() throws DataProcessingException { 116 String[] propertySum = {"time","sum"}; 117 String[] propertyCount = {"time","count"}; 118 String[] propertyAmount = {"amount"}; 119 String[] propertyCoordinate = {"time","coordinate"}; 120 String[] propertyIndicator = {"indicator"}; 121 String[] propertyThread = {"reference","thread"}; 122 123 definition = new ElementDefinition[7]; 124 125 classBuilder = new EntityBuilder("Class", "Class"); 126 definition[0] = classBuilder.buildDefinition(); 127 128 threadBuilder = new EntityBuilder("Thread", "Thread"); 129 definition[1] = threadBuilder.buildDefinition(); 130 131 methodBuilder = new EntityBuilder("Method", "Method"); 132 methodDefiningClass = methodBuilder.buildReferenceDefinition("Defining Class", classBuilder, null, "Defining class of the method"); 133 definition[2] = methodBuilder.buildDefinition(); 134 135 locationBuilder = new EntityBuilder("Location", "Location in Method"); 136 definition[3] = locationBuilder.buildDefinition(); 137 138 sizeBuilder = new EntityBuilder("Size", "Object Size"); 139 sizeBuilder.addComparator(new NumericStringComparator()); 140 definition[4] = sizeBuilder.buildDefinition(); 141 142 allocationBuilder = new EventBuilder("Object Allocation", "Object allocation event"); 143 allocationFieldSum = allocationBuilder.buildValueDefinition("Memory Allocated", propertySum, "Size of memory allocated"); 144 allocationFieldCounter = allocationBuilder.buildValueDefinition("Allocations", propertyCount, "Number of objects allocated"); 145 allocationObjectCount = allocationBuilder.buildValueDefinition("Object Count", propertyAmount, "Number of objects allocated"); 146 allocationObjectSize = allocationBuilder.buildValueDefinition("Memory Allocated", propertyAmount, "Size of memory allocated"); 147 allocationBytecode = allocationBuilder.buildValueDefinition("Bytecode", propertyCoordinate, "Bytecode sequence"); 148 allocationObjectType = allocationBuilder.buildReferenceDefinition("Object Type", classBuilder, null, "Type of the object"); 149 allocationThread = allocationBuilder.buildReferenceDefinition("Thread", threadBuilder, propertyThread, "Thread in which the object is allocated"); 150 allocationMethod = allocationBuilder.buildReferenceDefinition("Allocating Methods", methodBuilder, null, "Method that creates the object"); 151 allocationLocation = allocationBuilder.buildReferenceDefinition("Allocating Locations", locationBuilder, null, "Location where the object is created"); 152 allocationSize = allocationBuilder.buildReferenceDefinition("Allocation Size", sizeBuilder, null, "Allocation Size"); 153 definition[5] = allocationBuilder.buildDefinition(); 154 155 invocationBuilder = new EventBuilder("Method Invocation", "Method invocation event"); 156 invocationFieldCounter = invocationBuilder.buildValueDefinition("Invocations", propertyCount, "Total number of invocations"); 157 invocationNumber = invocationBuilder.buildValueDefinition("Number of Invocations", propertyAmount, "Total number of invocations"); 158 invocationBytecode = invocationBuilder.buildValueDefinition("Bytecode", propertyCoordinate, "Bytecode sequence"); 159 invocationThread = invocationBuilder.buildReferenceDefinition("Thread", threadBuilder, propertyThread, "Thread in which the method is invoked"); 160 invocationMethod = invocationBuilder.buildReferenceDefinition("Method", methodBuilder, null, "Method that is invoked"); 161 invocationLocation = invocationBuilder.buildReferenceDefinition("Invoking Locations", locationBuilder, null, "Location where the method is invoked"); 162 definition[6] = invocationBuilder.buildDefinition(); 163 164 definitionCounter = -1; 165 counter = new long[definition.length]; 166 for (int i=0; i<counter.length; i++) 167 counter[i] = 0; 168 } 169 170 public ElementDefinition getNextDefinition() throws DataProcessingException { 171 definitionCounter++; 172 if (definitionCounter < definition.length) { 173 return definition[definitionCounter]; 174 } else { 175 return null; 176 } 177 } 178 179 private String getSub(String line, int part) { 180 int start = line.indexOf(' ') + 1; 181 int i = 1; 182 while (i < part) { 183 start = line.indexOf(' ', start) + 1; 184 i++; 185 } 186 int end = line.indexOf(' ', start); 187 if (end == -1) { 188 return line.substring(start); 189 } else { 190 return line.substring(start, end); 191 } 192 } 193 194 public void startBuildEntity() throws DataProcessingException { 195 try { 196 file.seek(0); 197 198 classMap = new TreeMap(); 199 threadMap = new TreeMap(); 200 methodMap = new TreeMap(); 201 locationMap = new TreeMap(); 202 sizeMap = new TreeMap(); 203 } catch (IOException e) { 204 throw new DataProcessingException("File processing failed."); 205 } 206 } 207 208 public Entity getNextEntity() throws DataProcessingException { 209 try { 210 Entity returnVal = null; 211 String line = file.readLine(); 212 213 while ((returnVal == null) && (line != null) && (line.length()>0)) { 214 line = line.trim(); 215 char ch = line.charAt(0); 216 217 if (ch == 'C') { 218 classBuilder.newEntity(getSub(line, 1)); 219 returnVal = classBuilder.buildEntity(); 220 classMap.put(getSub(line, 2), returnVal); 221 } else if (ch == 'T') { 222 threadBuilder.newEntity(getSub(line, 1)); 223 returnVal = threadBuilder.buildEntity(); 224 threadMap.put(getSub(line, 2), returnVal); 225 } else if (ch == 'M') { 226 methodBuilder.newEntity(getSub(line, 1)); 227 methodBuilder.addReferenceField(methodDefiningClass, (Entity)(classMap.get(getSub(line, 3)))); 228 returnVal = methodBuilder.buildEntity(); 229 methodMap.put(getSub(line, 2), returnVal); 230 } else if (ch == 'L') { 231 locationBuilder.newEntity(getSub(line, 1)); 232 returnVal = locationBuilder.buildEntity(); 233 locationMap.put(getSub(line, 2), returnVal); 234 } else if (ch == 'O') { 235 String size = getSub(line, 6); 236 if (!sizeMap.containsKey(size)) { 237 sizeBuilder.newEntity(size); 238 returnVal = sizeBuilder.buildEntity(); 239 sizeMap.put(size, returnVal); 240 } 241 counter[5]++; 242 } else if (ch == '+') { 243 counter[6]+=2; 244 } 245 246 if (returnVal == null) { 247 line = file.readLine(); 248 } 249 } 250 251 return returnVal; 252 } catch (IOException e) { 253 throw new DataProcessingException("File processing failed."); 254 } 255 } 256 257 public void startBuildEvent() throws DataProcessingException { 258 try { 259 file.seek(0); 260 } catch (IOException e) { 261 throw new DataProcessingException("File processing failed."); 262 } 263 } 264 265 public Event getNextEvent() throws DataProcessingException { 266 try { 267 Event returnVal = null; 268 String line = file.readLine(); 269 270 while ((returnVal == null) && (line != null)) { 271 line = line.trim(); 272 char ch = line.charAt(0); 273 274 if (ch == 'O') { 275 allocationBuilder.newEvent(); 276 String size = getSub(line, 6); 277 allocationBuilder.addValueField(allocationObjectCount, 1); 278 allocationBuilder.addValueField(allocationObjectSize, Integer.parseInt(getSub(line, 6))); 279 allocationBuilder.addValueField(allocationFieldCounter, 1); 280 allocationBuilder.addValueField(allocationFieldSum, Integer.parseInt(getSub(line, 6))); 281 allocationBuilder.addValueField(allocationBytecode, Integer.parseInt(getSub(line, 1))); 282 allocationBuilder.addReferenceField(allocationObjectType, (Entity)(classMap.get(getSub(line, 5)))); 283 allocationBuilder.addReferenceField(allocationThread, (Entity)(threadMap.get(getSub(line, 2)))); 284 allocationBuilder.addReferenceField(allocationMethod, (Entity)(methodMap.get(getSub(line, 3)))); 285 allocationBuilder.addReferenceField(allocationLocation, (Entity)(locationMap.get(getSub(line, 4)))); 286 allocationBuilder.addReferenceField(allocationSize, (Entity)(sizeMap.get(size))); 287 returnVal = allocationBuilder.buildEvent(); 288 } else if (ch == '+') { 289 invocationBuilder.newEvent(); 290 invocationBuilder.addValueField(invocationNumber, 1); 291 invocationBuilder.addValueField(invocationFieldCounter, 1); 292 invocationBuilder.addValueField(invocationBytecode, Integer.parseInt(getSub(line, 1))); 293 invocationBuilder.addReferenceField(invocationThread, (Entity)(threadMap.get(getSub(line, 2)))); 294 invocationBuilder.addReferenceField(invocationMethod, (Entity)(methodMap.get(getSub(line, 3)))); 295 invocationBuilder.addReferenceField(invocationLocation, (Entity)(locationMap.get(getSub(line, 4)))); 296 returnVal = invocationBuilder.buildEvent(); 297 } else if (ch == '-') { 298 invocationBuilder.newEvent(true); 299 invocationBuilder.addValueField(invocationNumber, 1); 300 invocationBuilder.addValueField(invocationBytecode, Integer.parseInt(getSub(line, 1))); 301 invocationBuilder.addReferenceField(invocationThread, (Entity)(threadMap.get(getSub(line, 2)))); 302 invocationBuilder.addReferenceField(invocationMethod, (Entity)(methodMap.get(getSub(line, 3)))); 303 invocationBuilder.addReferenceField(invocationLocation, (Entity)(locationMap.get(getSub(line, 4)))); 304 returnVal = invocationBuilder.buildEvent(); 305 } 306 307 if (returnVal == null) { 308 line = file.readLine(); 309 } 310 } 311 312 return returnVal; 313 } catch (IOException e) { 314 throw new DataProcessingException("File processing failed."); 315 } 316 } 317 318 public String getName() { 319 return dsourceName; 320 } 321 322 public String getFileName() { 323 return fn; 324 } 325 326 public long getTotalNumberOfEvents() { 327 long total = 0; 328 329 for (int i=0; i<definition.length; i++) 330 total = total + counter[i]; 331 332 return total; 333 } 334 335 public long getNumberOfEvents(String definitionName) { 336 long number = 0; 337 338 for (int i=0; i<definition.length; i++) { 339 if (definition[i].getName().equals(definitionName)) { 340 number = counter[i]; 341 if (definitionName.equals("Method Invocation")) number = number/2; 342 break; 343 } 344 } 345 346 return number; 347 } 348 }